package com.piece.core.mongo.enums;

import com.piece.core.mongo.annotation.MongoQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.List;

/**
 * Mongo查询媒介
 */
public enum MongoType {

    EQUALS {
        @Override
        public Criteria buildCriteria(MongoQuery queryFieldAnnotation, Field field, Object value) {
            if (check(queryFieldAnnotation, field, value)) {
                String queryField = getQueryFieldName(queryFieldAnnotation, field);
                return Criteria.where(queryField).is(value.toString());
            }
            return new Criteria();
        }
    },

    LIKE {
        @Override
        public Criteria buildCriteria(MongoQuery queryFieldAnnotation, Field field, Object value) {
            if (check(queryFieldAnnotation, field, value)) {
                String queryField = getQueryFieldName(queryFieldAnnotation, field);
                return Criteria.where(queryField).regex(value.toString());
            }
            return new Criteria();
        }
    },

    GTE {
        @Override
        public Criteria buildCriteria(MongoQuery queryFieldAnnotation, Field field, Object value) {
            if (check(queryFieldAnnotation, field, value)) {
                if (value instanceof List) {
                    String queryField = getQueryFieldName(queryFieldAnnotation, field);
                    // 此处必须转型为List，否则会在in外面多一层[]
                    return Criteria.where(queryField).gte(value);
                }
            }
            return new Criteria();
        }
    },

    LTE {
        @Override
        public Criteria buildCriteria(MongoQuery queryFieldAnnotation, Field field, Object value) {
            if (check(queryFieldAnnotation, field, value)) {
                if (value instanceof List) {
                    String queryField = getQueryFieldName(queryFieldAnnotation, field);
                    // 此处必须转型为List，否则会在in外面多一层[]
                    return Criteria.where(queryField).lte(value);
                }
            }
            return new Criteria();
        }
    },

    IN {
        @Override
        public Criteria buildCriteria(MongoQuery queryFieldAnnotation, Field field, Object value) {
            if (check(queryFieldAnnotation, field, value)) {
                if (value instanceof List) {
                    String queryField = getQueryFieldName(queryFieldAnnotation, field);
                    // 此处必须转型为List，否则会在in外面多一层[]
                    return Criteria.where(queryField).in((List<?>) value);
                }
            }
            return new Criteria();
        }
    };

    /**
     * 判断字段是否为MongoDB字段
     */
    private static boolean check(MongoQuery queryField, Field field, Object value) {
        return !(null == queryField || null == field || null == value);
    }

    /**
     * 如果实体bean的字段上QueryField注解没有设置attribute属性时，默认为该字段的名称
     */
    private static String getQueryFieldName(MongoQuery queryField, Field field) {
        String queryFieldValue = null;
        queryFieldValue = queryField.attribute();
        if (!StringUtils.hasText(queryFieldValue)) {
            queryFieldValue = field.getName();
        }
        return queryFieldValue;
    }

    public abstract Criteria buildCriteria(MongoQuery queryFieldAnnotation, Field field, Object value);
}